/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "kh_sle_c_interface_test_entry.h"
#include "kh_sle_host.h"
#include "sle_error_code.h"
#include "sle_unit_test_log.h"
#include "stdlib.h"

SleHostCallbacks *g_hostUtCbs = NULL;

void OnSleUtHostStateChangeCallback(SleDeviceState state)
{
    SLE_UT_LOG("[KhSleHostTest][PASSED]OnSleUtHostStateChangeCallback state(%d)", state);
    return;
}

void InitSleHostServiceTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = InitSleHostService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]InitSleHostServiceTestLevel0 failed(%d)", ret);
}

void DeinitSleHostServiceTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = DeinitSleHostService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]DeinitSleHostServiceTestLevel0 failed(%d)", ret);
}

void RegisterHostCallbacksTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = RegisterHostCallbacks(g_hostUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]RegisterHostCallbacksTestLevel0 failed(%d)", ret);
}

void UnregisterHostCallbacksTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = UnregisterHostCallbacks(g_hostUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]UnregisterHostCallbacksTestLevel0 failed(%d)", ret);
}

void SleEnableTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = SleEnable();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]SleEnableTestLevel0 failed(%d)", ret);
}

void GetSleStateTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    SleDeviceState state;
    ret = GetSleState(&state);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]GetSleStateTestLevel0 failed(%d)", ret);
}

SleDeviceAddress randHostAddr = {
    .addrType = SLE_RANDOM_ADDRESS_TYPE,
    .addr = {1,1,1,1,1,1}
};

void GetHostAddressTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    SleDeviceAddress addr;
    addr.addrType = SLE_RANDOM_ADDRESS_TYPE;
    ret = GetHostAddress(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]GetHostAddressTestLevel0 failed1(%d)", ret);

    addr.addrType = SLE_PUBLIC_ADDRESS_TYPE;
    ret = GetHostAddress(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]GetHostAddressTestLevel0 failed2(%d)", ret);
}

static char hostName[SLE_DEVICE_NAME_LEN] = {'k','h','_','n','a','m','e','\0'};
void SetHostNameTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = SetHostName((const uint8_t *)hostName, 8);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]SetHostNameTestLevel0 failed(%d)", ret);
}

void GetHostNameTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    uint8_t name[SLE_DEVICE_NAME_LEN] = {0};
    uint8_t len = SLE_DEVICE_NAME_LEN;
    ret = GetHostName(name, &len);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]GetHostNameTestLevel0 failed(%d)", ret);
}

void SleDisableTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = SleDisable();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]SleDisableTestLevel0 failed(%d)", ret);
}

/** khSleHostTest with correct input param */
void KhSleHostTestLevel0(void)
{
    SLE_UT_LOG("__KhSleHostTestLevel0 start");
    InitSleHostServiceTestLevel0();
    RegisterHostCallbacksTestLevel0();
    SleEnableTestLevel0();
    GetSleStateTestLevel0();

    GetHostAddressTestLevel0();
    SetHostNameTestLevel0();
    GetHostNameTestLevel0();

    SleDisableTestLevel0();
    GetSleStateTestLevel0();
    UnregisterHostCallbacksTestLevel0();
    DeinitSleHostServiceTestLevel0();
    SLE_UT_LOG("__KhSleHostTestLevel0 end");
}

void InitSleHostServiceTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = InitSleHostService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]InitSleHostServiceTestLevel1 failed1(%d)", ret);
    //测试重复调用
    ret = InitSleHostService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]InitSleHostServiceTestLevel1 failed2(%d)", ret);
}

void DeinitSleHostServiceTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = DeinitSleHostService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]DeinitSleHostServiceTestLevel1 failed1(%d)", ret);
    //测试重复调用
    ret = DeinitSleHostService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_NOT_READY, "[KhSleHostTest][FAILED]DeinitSleHostServiceTestLevel1 failed2(%d)", ret);
}

void RegisterHostCallbacksTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    // 检查入参为NULL
    ret = RegisterHostCallbacks(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleHostTest][FAILED]RegisterHostCallbacksTestLevel1 failed1(%d)", ret);

    // 检查重复调用    
    ret = RegisterHostCallbacks(g_hostUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]RegisterHostCallbacksTestLevel1 failed2(%d)", ret);
    ret = RegisterHostCallbacks(g_hostUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]RegisterHostCallbacksTestLevel1 failed2(%d)", ret);
}

void UnregisterHostCallbacksTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //检查入参为NULL
    ret = UnregisterHostCallbacks(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleHostTest][FAILED]UnregisterHostCallbacksTestLevel1 failed1(%d)", ret);

    //检查入参为未注册的地址
    SleHostCallbacks callbacks = {0};
    ret = UnregisterHostCallbacks(&callbacks);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleHostTest][FAILED]UnregisterHostCallbacksTestLevel1 failed2(%d)", ret);
    
    //检查重复注销
    UnregisterHostCallbacksTestLevel0();
    ret = UnregisterHostCallbacks(g_hostUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]UnregisterHostCallbacksTestLevel1 failed3(%d)", ret);
}

void SleEnableTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = SleEnable();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]SleEnableTestLevel1 failed1(%d)", ret);
    //检查重复调用
    ret = SleEnable();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_ENABLE_SUCCESS_WHEN_ENABLED, "[KhSleHostTest][FAILED]SleEnableTestLevel1 failed2(%d)", ret);
}

void GetSleStateTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //检查入参为NULL
    ret = GetSleState(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleHostTest][FAILED]GetSleStateTestLevel1 failed1(%d)", ret);
    SleDeviceState state;
    ret = GetSleState(&state);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]GetSleStateTestLevel1 failed2(%d)", ret);
}

void GetHostAddressTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    SleDeviceAddress addr;
    addr.addrType = SLE_RANDOM_ADDRESS_TYPE;
    //测试入参为NULL
    ret = GetHostAddress(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleHostTest][FAILED]GetHostAddressTestLevel1 failed1(%d)", ret);

    ret = GetHostAddress(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]GetHostAddressTestLevel1 failed2(%d)", ret);
    addr.addrType = SLE_PUBLIC_ADDRESS_TYPE;
    ret = GetHostAddress(&addr);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]GetHostAddressTestLevel1 failed3(%d)", ret);
}

void SetHostNameTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    uint8_t name[SLE_DEVICE_NAME_LEN + 1] = {0};

    //测试入参len = 0
    ret = SetHostName(name, 0);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleHostTest][FAILED]SetHostNameTestLevel1 failed1(%d)", ret);
    //测试入参len > SLE_DEVICE_NAME_LEN
    ret = SetHostName(name, SLE_DEVICE_NAME_LEN + 1);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleHostTest][FAILED]SetHostNameTestLevel1 failed2(%d)", ret);
    //测试入参为NULL
    ret = SetHostName(NULL, 6);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleHostTest][FAILED]SetHostNameTestLevel1 failed4(%d)", ret);
    name[6] = 6;
    ret = SetHostName(name, 6);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]SetHostNameTestLevel1 failed5(%d)", ret);
}

void GetHostNameTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    uint8_t name[SLE_DEVICE_NAME_LEN] = {0};
    uint8_t len = SLE_DEVICE_NAME_LEN;
    //测试入参为NULL
    ret = GetHostName(NULL, &len);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleHostTest][FAILED]GetHostNameTestLevel1 failed1(%d)", ret);
    ret = GetHostName(name, NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleHostTest][FAILED]GetHostNameTestLevel1 failed2(%d)", ret);
    ret = GetHostName((uint8_t *)name, &len);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]GetHostNameTestLevel1 failed3(%d)", ret);
}

void SleDisableTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = SleDisable();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]SleDisableTestLevel1 failed1(%d)", ret);
    ret = SleDisable();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_DISABLE_SUCCESS_WHEN_DISABLED, "[KhSleHostTest][FAILED]SleDisableTestLevel1 failed2(%d)", ret);
}

/** khSleHostTest with invalid input param */
void KhSleHostTestLevel1(void)
{
    SLE_UT_LOG("__KhSleHostTestLevel1 start");
    InitSleHostServiceTestLevel1();
    RegisterHostCallbacksTestLevel1();
    SleEnableTestLevel1();
    GetSleStateTestLevel1();

    GetHostAddressTestLevel1();
    SetHostNameTestLevel1();
    GetHostNameTestLevel1();

    SleDisableTestLevel1();
    GetSleStateTestLevel1();
    UnregisterHostCallbacksTestLevel1();
    DeinitSleHostServiceTestLevel1();
    SLE_UT_LOG("__KhSleHostTestLevel1 start");
}

SleErrorCode InitKhSleHostTestEntry(void)
{
    g_hostUtCbs = (SleHostCallbacks*)malloc(sizeof(SleHostCallbacks));
    g_hostUtCbs->OnSleHostStateChangeCb = OnSleUtHostStateChangeCallback;
    return SLE_NO_ERROR;
}

SleErrorCode DeinitKhSleHostTestEntry(void)
{
    free(g_hostUtCbs);
    return SLE_NO_ERROR;
}

void KhSleHostTestEntry(void)
{
    SLE_UT_LOG("__KhSleHostTestEntry start");
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = InitKhSleHostTestEntry();
    SLE_UT_CHECK_AND_RETURN_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]InitKhSleHostTestEntry failed(%d)", ret);
    KhSleHostTestLevel0();
    KhSleHostTestLevel1();
    ret = DeinitKhSleHostTestEntry();
    SLE_UT_CHECK_AND_RETURN_LOG(ret == SLE_NO_ERROR, "[KhSleHostTest][FAILED]DeinitKhSleHostTestEntry failed(%d)", ret);
    SLE_UT_LOG("__KhSleHostTestEntry end");
}
